package com.framework.common.utils;

import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.redisson.api.*;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
@AllArgsConstructor
@Log4j2
public class RedisUtils {

    private final RedissonClient redissonClient;


    public <T> boolean set(String key, T value) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        bucket.set(value);
        return true;
    }

    /**
     * 向缓存中设置字符串内容
     *
     * @param key   key
     * @param value value
     * @return
     * @throws Exception
     */
    public boolean set(String key, String value, long time) {
        RBucket<String> bucket = redissonClient.getBucket(key);
        if (time < 0) {
            bucket.set(value);
        } else {
            bucket.set(value, time, TimeUnit.SECONDS);
        }
        return true;
    }

    /**
     * 向缓存中设置对象
     *
     * @param key
     * @param value
     * @return
     */
    public <T> boolean set(String key, T value, long time) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        if (time < 0) {
            bucket.set(value);
        } else {
            bucket.set(value, time, TimeUnit.SECONDS);
        }
        return true;
    }

    /**
     * 删除缓存中得对象，根据key
     *
     * @param key
     * @return
     */
    public boolean del(String key) {
        RBucket<Object> bucket = redissonClient.getBucket(key);
        bucket.delete();
        return true;
    }

    /**
     * 根据key 获取内容
     *
     * @param key
     * @return
     */
    public Object get(String key) {
        RBucket<Object> bucket = redissonClient.getBucket(key);
        return bucket.get();
    }


    /**
     * 根据key 获取对象
     *
     * @param key
     * @return
     */
    public <T> T get(String key, Class<T> clazz) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        return bucket.get();
    }


    /**
     * 获取分布锁
     *
     * @param key
     * @param seconds
     * @return
     * @throws InterruptedException
     */
    public boolean tryLock(String key, long seconds) throws InterruptedException {
        RLock lock = redissonClient.getLock(key);
        Boolean aBoolean = lock.tryLock(seconds, seconds, TimeUnit.SECONDS);
        log.info("aBoolean : " + aBoolean);
        return aBoolean;
    }


    /**
     * 释放分布锁
     *
     * @param key
     * @param key
     * @return
     * @throws InterruptedException
     */
    public void unlock(String key) throws InterruptedException {
        RLock lock = redissonClient.getLock(key);
        if (lock.isLocked()) {
            lock.unlock();
        }
    }


    public long incr(String key, long time) {
        RAtomicLong rAtomicLong = redissonClient.getAtomicLong(key);
        long number = rAtomicLong.incrementAndGet();
        rAtomicLong.expire(time, TimeUnit.SECONDS);
        return number;
    }

}
